/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package com.flexengine.math;

/**
 * @author Luann R. Athayde
 * @version 1.0
 * @since 1.0
 */
public class Point2D extends Form {

    private float x;
    private float y;

    public Point2D(float x, float y) {
        this.x = x;
        this.y = y;
    }
    public Point2D(Point2D p) {
        if( p != null ) {
            this.x = p.x;
            this.y = p.y;
        }
        else {
            this.x = 0;
            this.y = 0;
        }
    }
    public Point2D() {
        this(0f,0f);
    }

    public void setLocation(Point2D p) {
        if( p == null ) return;
        x = p.x;
        y = p.y;
    }
    public Point2D setLocation(float x, float y) {
        this.x = x;
        this.y = y;
        return this;
    }
    public Point2D getLocation() {
        return new Point2D(x, y);
    }

    public Point2D translate(float dx, float dy) {
        x += dx;
        y += dy;
        return this;
    }
    
    public Point2D move(float x, float y) {
        this.x = x;
        this.y = y;
        return this;
    }

    public float getX() {
        return this.x;
    }

    public float getY() {
        return this.y;
    }

    public void setX(float x) {
        this.x = x;
    }

    public void setY(float y) {
        this.y = y;
    }
    
    public void addX(float x) {
        this.x += x;
    }
    public void addY(float y) {
        this.y += y;
    }

    public float distanceSq(float x1, float y1, float x2, float y2) {
        x1 -= x2;
        y1 -= y2;
        return (x1 * x1 + y1 * y1);
    }
    public float distanceSq(float x, float y) {
        return distanceSq(this.x, this.y, x, y);
    }

    public float distance(float x1, float y1, float x2, float y2) {
        x1 -= x2;
        y1 -= y2;
        return (float) Math.sqrt(x1 * x1 + y1 * y1);
    }
    
    public float distance(float x, float y) {
        return distance(this.x, this.y, x, y);
    }
    
    public float distance(Point2D p) {
        return distance(p.getX(), p.getY());
    }
    
    /**
     * Gives the distance from this point to straight (v)...
     * @param v
     * @return 
     */
    public float distance(Vector2D v) {
        float coefficients[] = v.straightCoefficients();
        return (float)( Math.abs(coefficients[0]*getX() + coefficients[1]*getY() + coefficients[2]) /
                Math.sqrt(Math.pow(coefficients[0], 2) + Math.pow(coefficients[1], 2)) );
    }
    
    /**
     * Calcule the distance from [a] to [b]...
     * @param a
     * @param b
     * @return 
     */
    public float distance(Point2D a, Point2D b) {
        return distance(a.getX(), a.getY(), b.getX(), b.getY());
    }

    @Override
    protected Point2D clone() {
        return new Point2D(x, y);
    }
    
    @Override
    public boolean equals(Object obj) {
        if( obj != null && obj instanceof Point2D ) {
            Point2D tmp = (Point2D) obj;
            if( tmp.x == this.x && tmp.y == y )
                return true;
        }
        return false;
    }

    public boolean equals(Point2D p) {
        if( p != null ) {
            if(this.x == p.x && this.y == p.y) {
                return true;
            }
        }
        return false;
    }
    
    @Override
    public int hashCode() {
        int hash = 7;
        hash = 79 * hash + Float.floatToIntBits(this.x);
        hash = 79 * hash + Float.floatToIntBits(this.y);
        return hash;
    }
    
    @Override
    public String toString() {
        return getName()+"("+x+","+y+")";
    }
    
}
